package com.gosuncn.FileCopy;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

/***
 *HttpURLConnection 实现文件传输
 * @author zxl
 * @date 2021/9/1
 * @param
 * @return
*/
public class HttpClientHandle {

    //连接超时时间
    private static int HttpTimeOut = 6000;
    //请求方式
    private static String Method_Post ="POST";



    /**
     * 通过http请求建立连接
     * @param serverUrl
     * @param fileName
     */
    public HttpURLConnection initConnection(String serverUrl,String fileName){
        HttpURLConnection conn =null;
        try {
            //得到网络访问对象HttpURLConnection
            conn = (HttpURLConnection) new URL(serverUrl).openConnection();
            //从主机读取数据的超时时间
            conn.setReadTimeout(HttpTimeOut);
            // 连接主机的超时时间
            conn.setConnectTimeout(HttpTimeOut);
            //请求方式 post   这里如果用get请求会有异常
            conn.setRequestMethod(Method_Post);
            //分段进行传输 不然默认是本地将文件全部写入再进行传输，不然会报OOM内存溢出
            conn.setChunkedStreamingMode(1024);
            //默认是ture  可以调用getInputStream（）方法
            conn.setDoInput(true);
            //默认是false 设置ture 可以调用getOutputStream（）方法
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type","application/multipart/form-data;charset=UTF-8");
            //URLEncoder.encode(fileName,"UTF-8")防止中文乱码
            conn.setRequestProperty("fileName", URLEncoder.encode(fileName,"UTF-8"));
            //建立连接
            conn.connect();
            return conn;
        } catch (IOException e) {
            System.out.println("服务器连接失败");
            e.printStackTrace();
            return null;
        }
    }

    /**
     *   给服务器发送文件流
     * @param serverUrl  访问的服务器的url路径
     * @param fileName   需要同步的文件名（包含文件夹）
     * @param filePath   需要同步文件的路径
     * @return
     * @throws Exception
     */
    public  String sendHttpfile(String serverUrl,String fileName,String filePath) throws Exception {

        FileInputStream fis =null;
        BufferedInputStream bis = null;
        OutputStream dos = null;
        HttpURLConnection conn =null;

        try {
            //通过url访问与服务器建立连接
            conn = initConnection(serverUrl, fileName);
            ////判断响应状态码为200
            if (conn!=null){
                //DataOutputStream数据输出流  是对普通流的功能的一个扩展，可以更加方便地读取int,long,字符等类型数据 。
                dos = conn.getOutputStream();
                //获取文件的输入流
                fis = new FileInputStream(new File(filePath));

                //写入缓存流当中，避免了大量的磁盘IO
                bis = new BufferedInputStream(fis);

//                byte[] buffer1 = new byte[1024];
//                int len1;
//                while ((len1=bis.read(buffer1)) != -1){
//                    String s = new String(buffer1,0,len1);
//                    System.out.println(s);
//                }

                byte[] buffer = new byte[1024];
                int len;
                while ((len =bis.read(buffer)) != -1){
                    dos.write(buffer,0,len);
                }
//            dos.write("我发数据过来了".getBytes());
                System.out.println("响应结果: "+conn.getResponseCode());
                return "数据发送成功";
            }
            return "通过http请求建立连接失败";

        } catch (Exception e) {
            e.printStackTrace();
            return "客户端文件传输异常";
        } finally {
            if (bis !=null){
                bis.close();
            }
            if (fis !=null){
                fis.close();
            }
            if (dos !=null){
                dos.close();
            }
            if (conn !=null){
                conn.disconnect();
            }
        }
    }


    /**
     * 获取指定目录下的所有文件
     * @param folder
     * @throws Exception
     */
    public  void getAllFileByFolder(String folder) throws Exception {
        HttpClientHandle clientHandle = new HttpClientHandle();
        //获取文件夹
        File file = new File(folder);
        //获取文件夹里全部文件名
        String[] list = file.list();
        //创建临时文件指针
        File temp = null;
        //遍历所有文件

        for (int i = 0; i < list.length; i++) {
            //文件路径  这里必须要加"/"，不然如果是文件夹下一次访问就路径出错
            String filePath = folder +"/"+list[i];

            // D:\oldpath/zxl/123.txt 获取给定目录下的所有文件目录 /zxl/123.txt
            String folder1 = filePath.substring(filePath.indexOf("/")+1);
            System.out.println("需要同步的文件路径: "+filePath);
            //创建临时文件指针
            temp = new File(filePath);
            //如果是文件
            if (temp.isFile()) {
                clientHandle.sendHttpfile("http://localhost:8081/file/upload1",folder1, filePath);
            }
            //如果是文件夹
            if (temp.isDirectory()) {
                clientHandle.getAllFileByFolder(filePath);
            }

        }


    }


    public static void main(String[] args) throws Exception{
        //初始文件夹目录
        String folderPath = "D:\\dirA";
        HttpClientHandle clientHandle = new HttpClientHandle();
        //获取该文件目录下的所有文件并同步到相应的服务器
        long start = System.currentTimeMillis();
        clientHandle.getAllFileByFolder(folderPath);
        long end = System.currentTimeMillis();
        System.out.println("---------文件同步总共所用时间："+(end-start));

//        String  file = "D:\\oldpath/zxl/123.txt";
//        File file1 = new File(file);
//        System.out.println(file.substring(0, file.lastIndexOf("/")));
//        System.out.println(file.substring(file.indexOf("/")+1));
//        System.out.println(file1.getName());


    }

}
